home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-25 | 12.2 KB | 291 lines | [TEXT/MPS ] |
- {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
- { UMenuSetup.p }
- { Copyright © 1984-1990 Apple Computer Inc. All rights reserved. }
-
- {[f-]}
- {
- T H E O R Y O F O P E R A T I O N
-
- This unit provides two features: It implements a command numbering
- system that is independent of menu/item placement, and implements a
- framework for optimizing menu setups.
-
- The command numbering system works by assigning commands a unique
- integer number, and providing a mechanism for mapping command numbers
- to menu/item pairs. A set of routines are provide to manipulate
- commands via their command number rather than their menu and item
- numbers.
-
- Each command can be assigned an integer command number from 1 to
- 32767. To associate a command number with a menu item, menu resources
- are defined with the 'cmnu' resource type--not the 'MENU' type. The
- 'cmnu' type is just like the 'MENU' type, with an additional command
- number field for each menu item. The PostRez Tool converts the
- 'cmnu' output of Rez into equivalent 'MENU' resources and one 'mntb'
- resource. The 'mntb' resource maps command numbers to menu/item pairs.
-
- The items of some menus cannot be determined until run-time. The font
- menu is an example. In such cases, no command number is assigned by
- you. Instead, the command number is equal to -(256 * menu + item).
-
- The procedure CmdToMenuItem converts a command number to a menu id
- and item number by the following method:
-
- - If the command number is positive, the command table is searched
- for the number. If it is found, CmdToMenuItem returns the corre-
- sponding menu id and item number. Otherwise the menu and item are
- zero.
-
- - If the command number is negative, the menu number is the upper eight
- bits, and the item number the lower eight bits, of the absolute value
- of the command number. (This implies that menu id's must be <= 127
- and item numbers must be <= 255.)
-
- The function CmdFromMenuItem converts menu/items to command numbers by
- the following method:
-
- - If the item number is positive, the command table is search for the
- given menu/item pair. If found, the corresponding command number is
- returned. If not found, the number returned is equal to
- -(256 * menu + item).
-
- - If the item number is negative, the number returned is equal to
- -item number.
-
- Note that CmdToMenuItem and CmdFromMenuItem work regardless of whether
- the command is actually installed in the menu bar. MacApp takes
- advantage of this feature by having a set of generic "buzz" commands,
- whose primary use is to set the name of the Undo command (e.g. 'Undo
- Drawing').
-
- The second feature of this unit is to optimize menu setups (changing
- the appearance of menus and items). Normally, each call to CheckItem,
- SetItemStyle and SetCmdIcon in turn calls CalcMenuSize because the width
- or height of the menu may have changed. If menu setups are done all at
- one time, then CalcMenuSize can be deferred until the end of the setup
- process. The procedure PerformMenuSetup implements this mechanism. It
- relies on the fact that menu setups are done all at once, and that you
- will call SetCmdName, SetItemStyle and SetCmdIcon instead of SetItem,
- SetItemStyle and SetCmdIcon. It works only for menus whose id is from
- 1 to mLastMenu. Menus with IDs greater than mLastMenu are not affected
- by this scheme.
-
- PerformMenuSetup accepts one parameter, a procedure which actually
- implements the menu appearance changes. SetupMenus performs the
- following steps:
-
- - Before calling your menu setup procedure, StartupMenuSetup is called.
- It disables all menus and items, remembers the current
- menu proc and enabled flags of each menu, and sets the MenuProc of
- each menu to gHNullMenuProc, thereby disabling CalcMenuSize.
- - Your procedure is called. It in turn calls SetCmdName,
- SetCmdStyle, SetCmdIcon, Enable, EnableCheck, or a
- Toolbox routine (provided it isn't SetItem, SetItemStyle or
- SetCmdIcon).
- - Menus with at least one enabled item are enabled, CalcMenuSize is
- called for those menus that need it, each menu's menuproc is restored,
- and DrawMenuBar is called if the enabled state of any menu changed.
- }
- {[f+]}
-
- {$IFC UNDEFINED UsingIncludes}
- {$SETC UsingIncludes := FALSE}
- {$ENDC}
-
- {$IFC NOT UsingIncludes}
- UNIT UMenuSetup;
-
- INTERFACE
- {$ENDC}
-
- {$IFC UNDEFINED __UMenuSetup__}
- {$SETC __UMenuSetup__ := FALSE}
- {$ENDC}
-
- {$IFC NOT __UMenuSetup__}
- {$SETC __UMenuSetup__ := TRUE}
-
- { • Required for this unit's interface. Auto-Include them }
- {$SETC UMenuSetupIncludes := UsingIncludes}
- {$SETC UsingIncludes := TRUE}
- {$I+}
- {$IFC UNDEFINED UsingTypes} {$I Types.p} {$ENDC}
- {$IFC UNDEFINED UsingMenus} {$I Menus.p} {$ENDC}
- {$SETC UsingIncludes := UMenuSetupIncludes}
-
- CONST
- kMNTBbyCmdNumber = 'mntb'; { menu command number table type }
- kIDMNTBbyCmdNumber = 128; { menu command number table ID }
-
- mFirstMenu = 1; { MacApp manages menu titles
- mFirstMenu..mLastMenu generically }
- mApple = mFirstMenu; { MacApp does not disable any commands in
- this menu }
- mFile = mApple + 1; { Default ID of the File menu }
- mEdit = mFile + 1; { Default ID of the Edit menu }
-
- mDebug = 900; { read in if debugging is turned on; number
- corresponds with debugging command numbers
- }
- mLastMenu = 63; { MacApp disables menu titles
- mFile..mLastMenu generically }
-
- TYPE
-
- CmdNumber = INTEGER; { CmdNumbers tell MacApp what verb is
- intended after mapping from menu/item. }
-
- VAR
- gMenusAreSetup: BOOLEAN; { set FALSE before every event; set TRUE by
- SetupTheMenus, which is called at Idle
- Begin; if your DoIdle changes the target
- or makes other changes that would alter
- the appearance of menus, you must set
- gMenusAreSetup to FALSE there. }
- gRedrawMenuBar: BOOLEAN; { if TRUE, then DrawMenuBar will be called
- by TApplication.SetupTheMenus. If you have
- menus that are not handled by MacApp, your
- implementation(s) of DoSetupMenus can set
- this to TRUE to force the menu bar to be
- redrawn. }
- {$IFC qDebug}
- gTraceSetupMenus: BOOLEAN;
- {$ENDC}
-
- { The following routines all recognize command numbers of the form -(256 * menu + item) and
- -(256 * menu). The former is used when there is no command number; the latter to
- enable/disable a whole menu (rare) }
-
- FUNCTION CmdEnabled(cmd: CmdNumber): BOOLEAN;
- { Returns true if the given cmd is currently enabled. }
-
- FUNCTION CmdFromMenuItem(menu, item: INTEGER): CmdNumber;
- { Returns the command number for the given menu ID and item number. If the item number is
- positive, the command table is search for the given menu/item pair. If found, the
- corresponding command number is returned. If not found, the number returned is equal to
- -(256 * menu + item). If the item number is negative, the number returned is equal to -item
- number. }
-
- PROCEDURE CmdToMenuItem(aCmd: CmdNumber;
- VAR menu, item: INTEGER);
- { CmdToMenuItem returns the menu ID and item number of the given command. If aCmd is
- positive, the command table is searched for aCmd. If it is found, CmdToMenuItem returns the
- corresponding menu ID and item number. Otherwise menu and item are set to zero. If aCmd is
- negative, the menu number is the upper eight bits, and the item number the lower eight
- bits, of the absolute value of aCmd. (This implies that menu id's must be <= 127 and item
- numbers must be <= 255.) }
-
- FUNCTION CmdToComponents(cmd: CmdNumber; VAR menuNo, itemNo: integer): MenuHandle;
- { CmdToComponents returns the menu ID and item number of the given command. as well as
- the MenuHandle if the cmd exists. Otherwise it returns nil. }
-
- PROCEDURE CmdToName(aCmd: CmdNumber;
- VAR menuText: Str255);
- { Return the text of the menu item for the given command. }
-
- PROCEDURE EachMenuDo(PROCEDURE DoToMenu(aMenuHandle: MenuHandle;
- isHierarchical: Boolean); includeHierarchical: Boolean);
- { Sequences thru each menu in menu bar with ID in [0..mLastMenu], calling DoToMenu for each
- menu. Handles mDebug as a special case. }
-
- PROCEDURE Enable(aCmd: CmdNumber;
- canDo: BOOLEAN);
- { Enable or disable a command }
-
- PROCEDURE EnableCheck(aCmd: CmdNumber;
- canDo: BOOLEAN;
- checkIt: BOOLEAN);
- { Enable/Disable and check/uncheck a command }
-
- FUNCTION GetResMenu(menuResID: INTEGER): MenuHandle;
- { Utility that just does GetResource('MENU', resourceID), so that it works for menus not
- currently in the menu bar. (You cannot call GetMenu more than once for the same menu, so
- you can use this (or MAGetMenu which is preferred) instead.) }
-
- PROCEDURE InitUMenuSetup;
- { Initializes this unit, and must be called before using any other part of this unit. Loads
- the command table and sets up the null menu proc. }
-
- FUNCTION MAGetNewMBar(menuRsrcID: INTEGER): Handle;
- { Equivalent to the Menu Manager's GetNewMBar except it explicitly sets the menu bar's
- colors.}
-
- PROCEDURE MAInsertMenu(theMenu: MenuHandle;
- beforeID: INTEGER);
- { Equivalent to the Menu Manager's InsertMenu with the addition that the MAInsertMenu looks
- for an 'mctb' resource whose id is the menu's id, and if it is present applies the 'mctb'
- to the menu.}
-
- FUNCTION MAGetMenu(menuNo: INTEGER): MenuHandle;
- { Not quite equivalent to GetMenu because it doesn't load the menuDefProc or color table yet.
- It does, however, let you get the menuhandle without calling GetMenu more than once. It tries
- the menubar first and then calls GetResMenu if necessary. }
-
- PROCEDURE NeedCalcMenuSize(aMenuHandle: MenuHandle);
- { This procedure is called as part of the menu setup process and indicates that the given
- menu needs CalcMenuSize. You must explicitly call this if you use change a menu by means
- other than those supplied in this unit (e.g. you insert or delete items from a menu).
- Failure to do so will result in improperly sized menus. }
-
- PROCEDURE SetCmdIcon(aCmd: CmdNumber;
- menuIcon: Byte);
- { You should call this (instead of the Toolbox's SetCmdIcon) for menus that are in the range
- [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's size
- needs to be recomputed. }
-
- PROCEDURE SetCmdName(aCmd: CmdNumber;
- menuText: Str255);
- { You should call this (instead of the Toolbox's SetItem) for menus that are in the range
- [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's size
- needs to be recomputed. }
-
- PROCEDURE SetIndCmdName(aCmd: CmdNumber;
- rsrcID, strIndex: INTEGER);
- { Does a GetIndString with the rsrcID & strIndex; and then a SetCmdName. }
-
- PROCEDURE SetMenuState(aCmd: CmdNumber;
- rsrcID, falseBuzzItem, trueBuzzItem: INTEGER;
- stateVariable: BOOLEAN);
- { IF stateVariable THEN
- SetIndCmdName(aCmd, rsrcID, trueBuzzItem)
- ELSE
- SetIndCmdName(aCmd, rsrcID, falseBuzzItem);
- }
-
- PROCEDURE SetStyle(aCmd: CmdNumber;
- aStyle: Style);
- { You should call this (instead of the Toolbox's SetItemStyle) for menus that are in the
- range [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's
- size needs to be recomputed. }
-
- PROCEDURE PerformMenuSetup(PROCEDURE TheMenuSetterUpper);
- { Routine that perfoms the menu setup. }
-
- PROCEDURE InvalidateMenus;
- { Invalidate all the items on all the menus. Just like invalidation for windows it doesn't
- immediately change the visual appearance when you invalidate, it just means they are invalid
- and should be "setup" before showing them to the user again. }
-
- PROCEDURE ValidateMenus;
- { Validate all the items on all the menus. Just like Validation for windows it doesn't
- immediately change the visual appearance when you Validate, it just means they don't need
- to be changed before showing them to the user again. }
-
- FUNCTION MenusHavePendingUpdate: BOOLEAN;
- { TRUE if the menus are invalid and should be "setup" before showing them to the user. }
-
- PROCEDURE InvalidateMenuBar;
- { Invalidate the menu bar. It should be redrawn again. }
-
- PROCEDURE ValidateMenuBar;
- { Validate the menu bar. It doesn't need redrawing, its just fine thank you. }
-
- FUNCTION MenuBarHasPendingUpdate: BOOLEAN;
- { TRUE if the menu bar is invalid and should be redrawn. }
-
- {$ENDC}
-
- {$IFC NOT UsingIncludes}
- END.
- {$ENDC}
-